package org.esisar.controller;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.esisar.controller.utils.SessionHelper;
import org.esisar.dao.AddressStatementCreator;
import org.esisar.dao.AlbumStatementCreator;
import org.esisar.dao.JDBCDAO;
import org.esisar.dao.OrderLineStatementCreator;
import org.esisar.dao.OrdersStatementCreator;
import org.esisar.dao.SizesStatementCreator;
import org.esisar.jdbc.JDBCConnector;
import org.esisar.model.Address;
import org.esisar.model.Model;
import org.esisar.model.OrderLine;
import org.esisar.model.Orders;
import org.esisar.model.Sizes;

public class OrderController extends HttpServlet{
	
	private JDBCDAO jdbcDao = new JDBCDAO();
	private Connection connection;
	private PreparedStatement preparedStatement;
	private ResultSet resultSet;
	private Orders order;
	
	public void doGet(HttpServletRequest req, HttpServletResponse res) 
			throws ServletException, IOException{

		String id = String.valueOf(SessionHelper.getUserId(req));

		if (req.getParameter("role") != null){
			try {
				List<Model> address = jdbcDao.findAll(new AddressStatementCreator(), "idClient", id);				
				if(address.size() == 0){
					req.setAttribute("message","You have to add an address for your account.");
					RequestDispatcher dispatcher = req.getRequestDispatcher("/User/panel.jsp");
					dispatcher.forward(req, res);
				}else{
					createOrder(req,res);
					req.setAttribute("address", address);
					RequestDispatcher dispatcher = req.getRequestDispatcher("/Order/Order.jsp");
					dispatcher.forward(req, res);
				}
				
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		if (req.getParameter("album") != null){
			try {
				List<Model> albums = jdbcDao.findAll(new AlbumStatementCreator(), "idClient", id);	
				req.setAttribute("albums", albums);			
				List<Model> sizes = jdbcDao.findAll(new SizesStatementCreator(), "idSize", "%");
				req.setAttribute("sizes", sizes);
				RequestDispatcher dispatcher = req.getRequestDispatcher("/Order/AddAlbum.jsp");
				dispatcher.forward(req, res);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		if (req.getParameter("order") != null){
				String idAddress = req.getParameter("idAddress");
				order.setIdAddress(Long.parseLong(idAddress));
				jdbcDao.updateDB(new OrdersStatementCreator(), order);
				RequestDispatcher dispatcher = req.getRequestDispatcher("/User/panel.jsp");
				dispatcher.forward(req, res);
		}
		
		if (req.getParameter("addAlbum") != null){
			try {
				if(!addAlbum(req,res))
					req.setAttribute("message", "This album is already on your order");
				List<Model> address = jdbcDao.findAll(new AddressStatementCreator(), "idClient", id);				
				req.setAttribute("address", address);
				RequestDispatcher dispatcher = req.getRequestDispatcher("/Order/Order.jsp");
				dispatcher.forward(req, res);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}	

	private boolean addAlbum(HttpServletRequest req, HttpServletResponse res) throws SQLException {
		String idSize = req.getParameter("idSize");
		String idAlbum = req.getParameter("idAlbum");
		int qty = Integer.parseInt(req.getParameter("qty")); 
		float price = ((Sizes) jdbcDao.findAll(new SizesStatementCreator(), "idSize", idSize).iterator().next()).getPrice();
		OrderLine ol = new OrderLine(order.getIdOrder(), Long.parseLong(idAlbum), Long.parseLong(idSize), qty, price);
		List<Model> ols = jdbcDao.findAll(new OrderLineStatementCreator(), "idOrder", order.getIdOrder() + "");
		for(Model x : ols){
			if(((OrderLine)x).getIdSize() == Long.parseLong(idSize) && ((OrderLine)x).getIdAlbum() == Long.parseLong(idAlbum))
				return(false);
		}
		jdbcDao.addToDB(new OrderLineStatementCreator(), ol);
		return(true);
	}

	private void createOrder(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException, SQLException {
		connection = JDBCConnector.JDBCConnector.connect();
		String id = String.valueOf(SessionHelper.getUserId(req));
		List<Model> addr = jdbcDao.findAll(new AddressStatementCreator(), "idClient", id);
		Address add = (Address) addr.iterator().next();
		try {
			//Insert order into database
			order = new Orders(new Date(),Long.parseLong(id),add.getIdAddress());
			preparedStatement = connection.prepareStatement("INSERT INTO orders (idOrder,orderDate,idClient,idAddress) VALUES(orders_sequence.nextval,?,?,?)", new String[] { "idOrder" });
			preparedStatement.setDate(1, new java.sql.Date(order.getOrderDate().getTime()));
			preparedStatement.setString(2, id);
			preparedStatement.setString(3, Long.toString(add.getIdAddress()));
			
			//Get its idOrder
			preparedStatement.executeUpdate();
			resultSet = preparedStatement.getGeneratedKeys();
			while(resultSet.next()){
				order.setIdOrder(resultSet.getLong(1));
			}
		} catch (SQLException e) {
			try {
				if (connection != null){
					connection.rollback();
				}
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			try {
				if (preparedStatement != null){
					preparedStatement.close();
				}

				if (connection != null){
					connection.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}